﻿//===================================================================
//
// Description: Sparqube Picture Column Lite for SharePoint 2010
// Web: http://www.sparqube.com/
//
//-------------------------------------------------------------------
//
// Copyright (C) 2012 ArtfulBits.CZ (development[at]artfulbits.cz)
// Web: http://www.artfulbits.cz/
//
//-------------------------------------------------------------------
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
// PARTICULAR PURPOSE.
//===================================================================

using System;
using System.IO;
using System.Web;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;

namespace Sparqube.SharePoint.PictureColumnLite
{
	internal class PictureUploader
	{
		#region Constants

		private static readonly char[] c_achSlashes = new char[] { '\\', '/' };

		#endregion //Constants

		#region Fields

		private PictureLiteField m_pictureField = null;
		private SPWeb m_web = null;

		#endregion //Fields

		#region Constructors

		public PictureUploader(PictureLiteField field, SPWeb web)
		{
			if (null == field)
			{
				throw new ArgumentException("field");
			}
			if (null == web)
			{
				throw new ArgumentException("web");
			}
			m_web = web;
			m_pictureField = field;
		}

		#endregion //Constructors

		#region Methods

		public string UploadPicture(HttpPostedFile httpFile)
		{
			int fileLength = httpFile.ContentLength;
			if (0 == fileLength)
			{
				throw new PictureUploadException(ResourceManager.GetResource(EResource.Error_NoFileUploaded));
			}

			string fileName = GetFileNameFromURL(httpFile.FileName);
			string fileExt = GetFileExtension(fileName);

			if (string.IsNullOrEmpty(fileExt) ||
				SPAdministrationWebApplication.Local.BlockedFileExtensions.Contains(fileExt.ToLowerInvariant()))
			{
				throw new PictureUploadException(ResourceManager.GetResource(EResource.Error_FileIsBlockedByAdministrator, fileName));
			}

			SPFolder folderStorage = GetPictureStorageFolder();
			if (null == folderStorage)
			{
				throw new PictureUploadException(ResourceManager.GetResource(EResource.Error_PictureStoragePathIsNotValid, m_pictureField.StorageFolderUrl));
			}

			byte[] bytesImage = GetProcessedImageBytes(httpFile.InputStream);

			string newFileName = string.Format("{0}.{1}", Guid.NewGuid().ToString("N"), fileExt);
			SPFile spfile = folderStorage.Files.Add(newFileName, bytesImage, true);

			string url = SPUrlUtility.CombineUrl(m_web.ServerRelativeUrl, spfile.Url);
			return url;
		}

        public SPFolder GetPictureStorageFolder()
        {
            return GetPictureStorageFolder(m_pictureField.StorageFolderUrl, m_web);
        }

		public static SPFolder GetPictureStorageFolder(string path, SPWeb web)
		{
			SPFolder result = null;

			if (null != path)
			{
				bool catchAccessDeniedException = SPSecurity.CatchAccessDeniedException;
				SPSecurity.CatchAccessDeniedException = false;
				try
				{
                    SPFolder folder = web.GetFolder(path) as SPFolder;
					if (folder.Exists)
					{
						result = folder;
					}
				}
				catch (Exception)
				{
				}
				finally
				{
					SPSecurity.CatchAccessDeniedException = catchAccessDeniedException;
				}
			}

			return result;
		}

		public bool DeletePicture(PictureLiteValue value)
		{
			bool success = false;

			SPFile file = GetUploadedFile(value);
			if (null != file)
			{
				bool allowUnsafeUpdates = m_web.AllowUnsafeUpdates;
				m_web.AllowUnsafeUpdates = true;
				bool catchAccessDeniedException = SPSecurity.CatchAccessDeniedException;
				SPSecurity.CatchAccessDeniedException = false;
				try
				{
					SPFolder folder = file.ParentFolder;
					SPList list = file.Item.ParentList;
					string fileName = file.Name;
					file.Delete();

					success = true;
				}
				catch { }
				finally
				{
					SPSecurity.CatchAccessDeniedException = catchAccessDeniedException;
					m_web.AllowUnsafeUpdates = allowUnsafeUpdates;
				}
			}
			return success;
		}

		#endregion //Methods

		#region Implementation

		private SPFile GetUploadedFile(PictureLiteValue value)
		{
			SPFile file = null;
			if ((null != value) && !string.IsNullOrEmpty(value.Url))
			{
				try
				{
					file = m_web.GetFileOrFolderObject(value.Url) as SPFile;
				}
				catch { }
			}
			return file;
		}

		private byte[] GetProcessedImageBytes(Stream stream)
		{
			byte[] bytesImage = null;

			int fileLength = (int)stream.Length;
			byte[] buffer = new byte[fileLength];
			stream.Seek(0, System.IO.SeekOrigin.Begin);
			if (stream.Read(buffer, 0, fileLength) == fileLength)
			{
				bytesImage = buffer;
			}

			return bytesImage;
		}

		private static string GetFileNameFromURL(string path)
		{
			string result = "";
			if (!string.IsNullOrEmpty(path))
			{
				int nIdx = path.LastIndexOfAny(c_achSlashes);
				result = (nIdx > 0) ? path.Substring(nIdx + 1) : path;
			}
			return result;
		}

		private static string GetFileExtension(string fileName)
		{
			string res = "";
			if (!string.IsNullOrEmpty(fileName))
			{
				int startIndex = fileName.LastIndexOf('.') + 1;
				if ((0 < startIndex) && (startIndex < fileName.Length))
				{
					res = fileName.Substring(startIndex).ToLowerInvariant();
				}
			}
			return res;
		}

		#endregion //Implementation

	}// PictureUploader
}
